package programming.in.scala

import scala.io.Source
import java.io.File

/**
  * Created by baiwf on 2017/5/30.
  */

object LongLines {
  def processFile(filename:String, width:Int): Unit = {
    val source = Source.fromFile(filename) //路径是相对于工程根路径！！
    for (line <- source.getLines()) {
      processLine(filename,width,line)
    }
  }

  private def processLine(filename:String,width:Int, line:String): Unit = {
    if (line.length > width) {
      println(filename + ": " + line.trim)
    }
  }

  //local function
  def processFile_LocalFunction(filename:String, width:Int): Unit = {
    def processLine(line:String): Unit = {
      if (line.length > width) {
        println(filename + ": " + line.trim)
      }
    }
    val source = Source.fromFile(filename) //路径是相对于工程根路径！！
    for (line <- source.getLines()) {
      processLine(line)
    }
  }

  def printDir(path:String): Unit = {
    for (d <- subdir(new File(path))) {
      println(d)
    }
  }
  private def subdir(dir:File): Iterator[File] = {
    val d = dir.listFiles.filter(_.isDirectory)
    val f = dir.listFiles().toIterator
    f ++ d.toIterator.flatMap(subdir _)
  }
}

object FunctionLiterals {
  def functionLiteral(): Unit = {
    val o = List(-1,-2,3,4)
    o.foreach((x:Int) => println(x))
    //也可以写成
    o.foreach(println _) //_不再是a placeholder of a single parameter,
    //but a placeholder for an entire parameter list

    o.filter((x:Int) => x>0)
    println("omit the parameter type:")
    o.filter((x) => x > 0)
    println("omit the parenthess:")
    o.filter(x => x>0)
    println("using underscore:")
    o.filter(_ > 0)

    val f = (_:Int) + (_:Int)  //这时必须要加Int, f 是一个<function2>，接收2个参数的函数
    println(f(1,2))
    val a = sum _ // a is <function3> instance
    // automatically generated by compiler from sum _
    println(a(1,2,3))

    val b = sum(1, _:Int, 3) //这时自动生成的类apply方法就只接受一个参数,apply内部会调用
    //有3个参数的sum方法
    println(b(2))

    var more = 1
    val closureFunc = (x:Int) => x + more //more是自由变量，由些function literal生成的
    //Function value叫做closure
    println(closureFunc(2))
    more = 2
    println("after more changed:" + closureFunc(2))

    var sum2 = 0
    o.foreach(sum2 += _)
    println("after using closure modifying sum2:" + sum2)
  }

  def sum(a:Int, b:Int, c:Int) = a + b + c
}

object ch08_functions_and_closures {
  def main(args: Array[String]): Unit = {
    FunctionLiterals.functionLiteral()
    //LongLines.printDir(".")
    //t1(args)
  }

  def t1(args:Array[String]): Unit = {
    val width = args(0).toInt
    for (arg <- args.drop(1)){ //drop舍弃前面的n个
      LongLines.processFile(arg,width)
    }
  }
}
